home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freaks Macintosh Archive
/
Freaks Macintosh Archive.bin
/
Freaks Macintosh Archives
/
Hacking & Misc
/
Mac Satellite.sit
/
Mac Satellite
/
MacSeason9 v1.7
/
MacSeason9v1.7
/
MacSeason9.src
/
decrypt9.c
next >
Wrap
Text File
|
1995-08-15
|
10KB
|
438 lines
/* Latest change: 15/08/95
Fixed access to addresses $0088 and $00EE.
12/08/95
Corrected implementation of nanocommand 0F. Perhaps this will work.
03/08/95
Fixed 'new' nanocommand 0F. Thanks to Ian for the fix.
10/07/95
Introduced the kernel counter as an attempt to get MacSeason running on
slow, slow Macs (read 68000/8Mhz)
07/07/95
I'm now using D0 instead of a global variable to pass the keybyte to
SkyKernel.
29/06/95
Reinstated nanocommand 28. Fixed a (stupid) bug. Maybe one day I'll learn
to count...
25/06/95
Some further optimizations for slower Macs.
15/06/95
Sky ECM: Nanocmd access to address $e7 fixed.
12/06/95
Some minor changes to further improve the speed of this routines.
29/05/95
I changed a lot of details to optimize performance when compiled with
Symantec C 7.0 on an 680x0 based Macintosh. One of the major changes was
the redefinition of SkyKernel with no parameters. This saves some stack
operations that would be necessary otherwise and thus saves processing
time.
Loops are now always do-while-loops, since Think C produces one branch
command more for while() or for-loops.
Also, I tried to avoid accessing the 32-byte message or the 8-byte answer
as an array. Access to an array like
theByte = msg[i];
usually gets translated into something like
move $00(Ax,Dx), Dx
which requires 14 clock periods on an 68000. Written as
theByte = *msg++;
it gets translated into
move (Ax)+, Dx
which requires only 8 clock periods on an 68000 and is perfectly well
suited for this purpose.
Another optimization was the use of the inline assembler to program
bit shifting with the rol.b or ror.b command. E.g. if you want to rotate
the byte aByte one bit to the left, in C you write something like this:
aByte = (aByte << 1) | (aByte >> 7);
Alas, Think C translates this into: (Dx being one of the data registers)
MOVE.B aByte,Dx
ASR.W #$7,Dx
ADD.B aByte,aByte ; same as 'ASL.W #$1, aByte' only faster
OR.B Dx,aByte
which does exactly the same as the rol.b #1,aByte command, only slower.
(32 clock cycles instead of 8 for the rol.b command.) Therefore the
rol.b command is used 'manually'. This requires aByte to be of type register.
Suggestions for further optimization welcome.
*/
#include "decrypt9.h"
#include "MacSeason9.h"
unsigned char theBigTable[16384];
unsigned char bTable[256];
short checksum;
short kernelCount;
extern short reallyDecode;
unsigned char theNanos[16];
unsigned char *cardReply; /* Global pointer to cardreply to save on some stack operations */
short oi;
extern vcPrefs prgPrefs;
unsigned char kPleaseWait[1] = {
0x60
};
unsigned char theKeyByte;
#define TABLESIZE 8192
#define HALFTABLE 4096
#define tBigTable 132
unsigned char nanoLengths[256];
void InitNanoLens( void )
{
short i;
i = 255;
do {
nanoLengths[i] = 0x10;
} while (--i >= 0);
nanoLengths[0x09] = 3;
nanoLengths[0x0C] = 2;
nanoLengths[0x11] = 4;
nanoLengths[0x14] = 5;
nanoLengths[0x19] = 1;
nanoLengths[0x1D] = 2;
nanoLengths[0x24] = 3;
nanoLengths[0x28] = 5;
nanoLengths[0x2c] = 1;
nanoLengths[0x30] = 2;
nanoLengths[0x34] = 4;
nanoLengths[0x39] = 2;
nanoLengths[0x3c] = 1;
nanoLengths[0x41] = 1;
nanoLengths[0x46] = 1;
nanoLengths[0x49] = 1;
}
void SkyKernel( void )
{
register unsigned short j,k;
asm {
movea.l cardReply, a1
moveq #2, d1
moveq #0, j
moveq #0, k
move.b (a1)+, k;
lea bTable, a0
@kernelLoop:
move.b k,j
move.b 0(a0,j), k
add.b d0, k
sub.b (a1), k
sub.b (a1)+, j
eor.b d0, j
mulu.w k, j
eor.b j, (a1)
move.b (a1)+, k
lsr.w #8, j
add.b j, (a1)
rol.b #1,d0
addi.b #0x49, d0
dbra d1, @kernelLoop
move.b j, theBigTable[0x1FFF - 0xE7]
move.b (a1), j
mulu.w k, j
subq #7, a1
moveq #0x39, k
move.b (a1), d0
add.b j, d0
addx.b k, d0
move.b d0, (a1)+
moveq #-113, k // -113 = 0x8f
lsr.w #8, j
move.b (a1), d0
add.b j, d0
addx.b k, d0
move.b d0, (a1)
move.b #6, theBigTable[0x1FFF - 0x88]
}
if (--kernelCount == 0) {
send( kPleaseWait, 1);
kernelCount = prgPrefs.kernelCount;
}
}
short decode( unsigned char *theMsg, unsigned char *answ)
{
register long i;
register unsigned char aChar;
register unsigned char theByte;
register unsigned char *nanoPtr;
register unsigned char *nanoEnd;
register unsigned char *msg;
register unsigned char c;
register unsigned char d;
register short NanoActive;
short offset;
kernelCount = prgPrefs.kernelCount;
aChar = 0x00;
theByte = 0x00;
msg = theMsg;
msg++;
cardReply = nanoPtr = answ;
asm {
// Clear 8 byte answer
clr.l (nanoPtr)+
clr.l (nanoPtr)
}
/* Calculate Nanocommands */
/* msg is already pointing to theMsg[1] */
asm {
move.b (msg)+, theByte
move.b (msg)+, aChar
eor.b aChar, theByte
rol.b #4, theByte;
rol.b #1, aChar
add.b theByte, aChar
}
if ((NanoActive = ((aChar ^ *msg++) - 0x80)) == 0) {
asm {
rol.b #1, aChar
add.b theByte, aChar
rol.b #1, aChar
add.b aChar, theByte
moveq #14, i
lea theNanos, nanoPtr
addq #8, msg
@calcnano:
move.b (msg)+, d0
eor.b theByte, d0
move.b d0, (nanoPtr)+
dbra i,@calcnano
}
}
checksum = 0;
if (reallyDecode) {
msg = theMsg;
/* Do decoding */
asm {
moveq #26, i
@loop27 move.b (msg)+, d0 //theKeyByte
jsr SkyKernel
dbra i,@loop27
}
theByte = 0x00;
i = 4; /* Check signature in bytes 27 - 30 */
nanoPtr = &answ[7]; /* This makes the loop a bit faster */
do {
asm {
move.b theByte, d0 //theKeyByte
jsr SkyKernel
move.b theByte, d0 //theKeyByte
jsr SkyKernel
move.b (msg)+, theByte
}
if ( theByte != *nanoPtr) checksum |= 1;
} while (--i);
theByte = *msg;
}
if (checksum == 0) {
if ((NanoActive==0)) {
if (prgPrefs.debug) DrawNanos( theNanos);
nanoPtr = &theNanos[0];
nanoEnd = &theNanos[16];
do {
asm {
move.b (nanoPtr), d0
}
case09:
asm {
cmpi.b #0x09, d0
bne @case0f
}
((unsigned char *)&offset)[0] = nanoPtr[1];
((unsigned char *)&offset)[1] = nanoPtr[2];
theByte = 0x63;
aChar = 0;
goto switchEnd;
case0f:
asm {
cmpi.b #0x0f, d0
bne @case11
}
theByte = nanoPtr[1];
nanoPtr = nanoEnd;
((unsigned char *)&offset)[0] = theBigTable[0x1fff - 0x00bf] & 0x1f;
((unsigned char *)&offset)[1] = theBigTable[0x1fff - 0x00c0];
goto case112;
case11:
asm {
cmpi.b #0x11, d0
bne @case19
}
theByte = nanoPtr[1];
((unsigned char *)&offset)[0] = 0x1f & nanoPtr[2];
((unsigned char *)&offset)[1] = nanoPtr[3];
case112:
aChar = theByte;
if (offset == 0x0081) {
aChar &= 0xb7;
aChar += 0x40;
} else if (offset == 0x00EE) {
nanoPtr = &theNanos[aChar];
}
theBigTable[0x1fff-offset] = aChar;
aChar = 0;
goto switchEnd;
case19:
asm {
cmpi.b #0x19, d0
bne @case28
}
theByte = nanoPtr - theNanos;
aChar = 0x19;
goto switchEnd;
case28:
asm {
cmpi.b #0x28, d0
bne @case30
}
/* this really copies the 4 following bytes to $8D-$90 */
aChar = nanoPtr - theNanos;
theByte = nanoPtr[4];
goto switchEnd;
case30:
asm {
cmpi.b #0x30, d0
bne @case39
}
i = nanoPtr[1];
msg = &theBigTable[0x1fff];
if ((char)msg[ -0x08] < 0) { // ECM 05/17/95
msg += 0x2000;
}
msg -= offset;
msg -= i;
asm {
@301: move.b (msg)+, d0 //theKeyByte
jsr SkyKernel
dbra i,@301
move.b -(msg), theByte
}
aChar = 0xff;
goto switchEnd;
case39:
asm {
cmpi.b #0x39, d0
bne @case46
}
theByte = ((unsigned char *)&offset)[1];
aChar = ((unsigned char *)&offset)[0];
break;
case46:
asm {
cmpi.b #0x46, d0
bne @dflt
}
goto exitdecode;
dflt: // also 0x03
asm {
cmpi.b #0x03, d0
beq @nanoLoopEnd
}
SysBeep(0);
goto nanoLoopEnd;
switchEnd:
asm {
move.b theByte, d0
jsr SkyKernel
move.b aChar, d0
jsr SkyKernel
}
nanoPtr += nanoLengths[*nanoPtr];
} while ((nanoPtr < nanoEnd));
nanoLoopEnd:
theByte = nanoPtr - theNanos;
} // if nanoActive
if (reallyDecode) {
asm {
moveq #63, i
@3 move.b theByte, d0 //theKeyByte
jsr SkyKernel
dbra i,@3
}
msg = theMsg;
asm {
moveq #0,aChar
moveq #31, i
@cs1 add.b (msg)+,aChar
dbra i,@cs1
}
if (aChar) checksum |= 2;
}
}
if ( checksum ) {
nanoPtr = answ; /* use a register */
asm {
clr.l (nanoPtr)+
clr.l (nanoPtr)
subq.l #4,nanoPtr
move.b #1,(nanoPtr)
}
}
exitdecode:
return(checksum);
}
void InitDecode( void )
{
Handle theRes;
short j,k;
unsigned char d, e;
unsigned char *theTable;
theRes = GetResource(tableResource,tBigTable);
HLock(theRes);
theTable = (unsigned char *)*theRes;
j = 0;
d = *theTable++;
do {
e = *theTable++;
if (e == d) {
k = *theTable++;
e = *theTable++;
do {
theBigTable[j] = e;
j++;
}
while (--k);
} else {
theBigTable[j] = e;
j++;
}
}
while (j < TABLESIZE);
theTable = theBigTable;
for (j = 0; j < HALFTABLE; j++) {
*theTable ^= theTable[1];
theBigTable[TABLESIZE+j] = theBigTable[HALFTABLE+j] + *theTable++;
theBigTable[HALFTABLE+j] = 0;
}
HUnlock(theRes);
ReleaseResource(theRes);
theRes = GetResource(tableResource,kSkyKeyTable);
HLock(theRes);
BlockMove(*theRes, bTable , 64);
BlockMove(*theRes, bTable+ 64, 64);
BlockMove( bTable, bTable+128, 128);
HUnlock(theRes);
ReleaseResource(theRes);
InitNanoLens();
}